package org.distributeme.core; import org.distributeme.core.conventions.SystemProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.Marker; import org.slf4j.MarkerFactory; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.rmi.server.ExportException; import java.util.concurrent.atomic.AtomicReference; /** * Utils for handling the RMIRegistry object. * * @author lrosenberg * @version $Id: $Id */ public class RMIRegistryUtil { /** * Marker for fatal log messages. */ private static Marker fatal = MarkerFactory.getMarker("FATAL"); /** * Logger. */ private static Logger log = LoggerFactory.getLogger(RMIRegistryUtil.class); /** * Reference to the rmi registry. */ private static final AtomicReference<Registry> reference = new AtomicReference<Registry>(); /** * Port on which the rmi registry exports its public api. */ private static int rmiRegistryPort; /** * Finds or creates a new registry. * * @return Returns created registry instance. * @throws java.rmi.RemoteException if any. */ public static Registry findOrCreateRegistry() throws RemoteException { return findOrCreateRegistry(-1); } /** * Finds or creates a new registry. * * @param port port to listen to. If port is below zero, it will be ignored. * @return Returns created registry instance. * @throws java.rmi.RemoteException if any. */ public static Registry findOrCreateRegistry(int port) throws RemoteException{ if (reference.get()!=null){ return reference.get(); } synchronized (reference) { log.info("Creating local registry"); Registry registry; if (port >0 || SystemProperties.LOCAL_RMI_REGISTRY_PORT.isSet()){ //we are hardcore bound to a local port try{ if (port <= 0) { port = SystemProperties.LOCAL_RMI_REGISTRY_PORT.getAsInt(); } log.info("Tying to bind to "+port); registry = LocateRegistry.createRegistry(port); log.info("Started local registry at port "+port); reference.set(registry); rmiRegistryPort = port; return registry; }catch(ExportException e){ log.error(fatal, "local rmi registry port specified but not useable", e); throw new AssertionError("Have to halt due to misconfiguration: local rmi registry port: "+SystemProperties.LOCAL_RMI_REGISTRY_PORT.get()+", port is not free or not bind-able "+e.getMessage()); }catch(NumberFormatException e){ log.error(fatal, "local rmi registry port specified but not parseable", e); throw new AssertionError("Have to halt due to misconfiguration: local rmi registry port: "+SystemProperties.LOCAL_RMI_REGISTRY_PORT.get()+", expected numeric value."); } }//... end SystemProperties.LOCAL_RMI_REGISTRY_PORT.isSet() RegistryLocation location = RegistryLocation.create(); int minPort = location.getRmiRegistryMinPort(); int maxPort = location.getRmiRegistryMaxPort(); int currentPort = minPort; while (currentPort <= maxPort){ try{ registry = LocateRegistry.createRegistry(currentPort); log.info("Started local registry at port "+currentPort); reference.set(registry); rmiRegistryPort = currentPort; //System.out.println("Reference "+registry+", port "+rmiRegistryPort); return registry; }catch(ExportException e){ currentPort++; } } //...while throw new RemoteException("Couldn't obtain free port for a local rmi registry"); } } /** * <p>Getter for the field <code>rmiRegistryPort</code>.</p> * * @return a int. */ public static int getRmiRegistryPort() { return rmiRegistryPort; } }